home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
195_01
/
format.c
< prev
next >
Wrap
Text File
|
1987-10-03
|
10KB
|
556 lines
/* [FORMAT.C of JUGPDS Vol.18]
*****************************************************************
* *
* Written by Hakuo Katayose (JUG-CP/M No.179) *
* 49-114 Kawauchi-Sanjuunin-machi *
* Sendai, Miyagi 980 *
* Phone: 0222-61-3219 *
* *
* Edited & tested by Y. Monma (JUG-C/M Disk Editor) *
* *
*****************************************************************
*/
/* format - text formatter
---------------------------------------------------------------------
# dot command break? default function
---------------------------------------------------------------------
1 .fi yes stat filling
2 .nf yes stop filling
3 .br n yes cause break
4 .ls n no n=1 line spacing is n
5 .bp n yes n=+1 begin page numbered n
6 .sp n yes n=1 space down n lines
7 .in n no n=0 indent n spaces
8 .rm n no n=60 set right margin to n
9 .ti n yes n=0 temporary indent of n
10 .ce n yes n=1 center nextn lines
11 .ul n no n=1 underline words from next n lines
12 .he no empty header title
13 .fo no empty footer title
14 .pl n no n=66 set page length to n
---------------------------------------------------------------------
.bp 1
.in 8
.rm 76
.he : program format.c #
*/
#include <stdio.h>
#include <dio.h>
#define UNKNOWN 0
#define FI 1
#define NF 2
#define BR 3
#define LS 4
#define BP 5
#define SP 6
#define IN 7
#define RM 8
#define TI 9
#define CE 10
#define UL 11
#define HE 12 /* Header enable */
#define FO 13
#define PL 14
#define SQUOTE '\''
#define DQUOTE '"'
#define PLUS '+'
#define MINUS '-'
#define COMMAND '.'
#define PAGENUM '#'
#define PAGELEN 66
#define PAGEWIDTH 60
#define MAXOUT 256
#define HUGE 1000
#define INSIZE 256
#define MAXLINE 256
#define YES 1
#define NO 0
int fill, /* fill if YES; init = YES */
lsval, /* current line spacing; init = 1 */
inval, /* current indent; >= 0; init = 0 */
rmval, /* current right margin; init = PAGEWIDTH = 60 */
tival, /* current temporary indent; init = 0 */
ceval, /* # of lines to center; init = 0 */
ulval, /* # of lines to underline; init = 0 */
curpag,
newpag,
lineno,
plval;
int m1val, m2val, m3val, m4val, bottom;
char __header[MAXLINE], __footer[MAXLINE], *header, *footer;
int outp, outw, outwds, dir;
char outbuf[(MAXOUT+1)];
/*
.bp
*/
main(argc, argv)
int argc;
char **argv;
{
char inbuf[MAXLINE], *line;
dioinit(&argc, argv);
if (argc < 2) {
error("Usage: format <infile >outfile ^Z");
exit();
}
init();
line = inbuf;
while (getlin(line, MAXLINE) > 0)
if (*line == COMMAND)
Comand(line);
else
Text(line);
if (lineno > 0)
LineSpace(HUGE);
dioflush();
}
/* comand - perform formatting command
.bp
*/
Comand(line)
char *line;
{
int ctyp, argtyp, val, spval;
if ((ctyp = ComandTyp(line)) == UNKNOWN)
return;
val = GetArgVal(line, &argtyp);
switch (ctyp) {
case FI :
brk();
fill = YES;
break;
case NF :
brk();
fill = NO;
break;
case BR :
brk();
break;
case LS :
lsval = set(lsval, val, argtyp, 1, 1, HUGE);
break;
case BP :
if (lineno > 0)
LineSpace(HUGE);
curpag = set(curpag, val, argtyp, curpag+1, -HUGE, HUGE);
newpag = curpag;
break;
case SP :
spval = set(spval, val, argtyp, 1, 0, HUGE);
LineSpace(spval);
break;
case IN :
inval = set(inval, val, argtyp, 0, 0, rmval-1);
tival = inval;
break;
case RM :
rmval = set(rmval, val, argtyp, PAGEWIDTH, tival+1, HUGE);
break;
case TI :
brk();
tival = set(tival, val, argtyp, 0, 0, rmval);
break;
case CE :
brk();
ceval = set(ceval, val, argtyp, 1, 0, HUGE);
break;
case UL :
ulval = set(ulval, val, argtyp, 0, 1, HUGE);
break;
case HE :
GetTitle(line, header);
break;
case FO :
GetTitle(line, footer);
break;
case PL :
plval = set(plval, val, argtyp, PAGELEN,
m1val + m2val + m3val + m4val + 1, HUGE);
bottom = plval - m3val - m4val;
break;
}
}
ComandTyp(line)
char *line;
{
char cmd[3];
++line; cmd[0] = toupper(*line);
++line; cmd[1] = toupper(*line);
cmd[2] = '\0';
if (!strcmp(cmd, "FI"))
return(FI);
else if (!strcmp(cmd, "NF"))
return(NF);
else if (!strcmp(cmd, "BR"))
return(BR);
else if (!strcmp(cmd, "LS"))
return(LS);
else if (!strcmp(cmd, "BP"))
return(BP);
else if (!strcmp(cmd, "IN"))
return(IN);
else if (!strcmp(cmd, "RM"))
return(RM);
else if (!strcmp(cmd, "TI"))
return(TI);
else if (!strcmp(cmd, "CE"))
return(CE);
else if (!strcmp(cmd, "UL"))
return(UL);
else if (!strcmp(cmd, "HE"))
return(HE);
else if (!strcmp(cmd, "FO"))
return(FO);
else if (!strcmp(cmd, "PL"))
return(PL);
return(UNKNOWN);
}
/* GetAgVal - get argument value */
GetArgVal(line, argtyp)
char *line;
int *argtyp;
{
while (!isspace(*line))
line++;
while (*line == ' ' || *line == '\t')
line++;
*argtyp = *line;
if (*line == PLUS || *line == MINUS)
line++;
return(atoi(line));
}
/* set - set parameter and check range */
set(param, val, argtyp, defval, minval, maxval)
{
if (argtyp == '\n')
param = defval;
else if (argtyp == PLUS)
param += val;
else if (argtyp == MINUS)
param -= val;
else
param = val;
param = min(param, maxval);
return max(param, minval);
}
/* Text - process text lines */
Text(line)
char *line;
{
char wrdbuf[INSIZE];
int i, len;
i = 0;
if (isspace(*line))
LeadBlank(line);
if (ceval > 0) {
tival = max((rmval + tival - width(line))/2, 0);
put(line);
ceval--;
}
else if (*line == '\n')
put(line);
else if (fill == NO)
put(line);
else
while (GetWord(line, &i, wrdbuf) > 0)
PutWord(wrdbuf);
}
/* put - put out line with proper spacing andindenting */
put(line)
char *line;
{
int i;
if (lineno == 0 || lineno > bottom)
phead();
for (i = 0; i < tival; i++)
putchar(' ');
tival = inval;
puts(line);
skip(min(lsval-1, bottom - lineno));
lineno += lsval;
if (lineno > bottom)
pfoot();
}
LineSpace(i)
{
brk();
if (lineno > bottom)
return;
if (lineno == 0)
phead();
skip(min(i,bottom + 1 - lineno));
lineno += i;
if (lineno > bottom)
pfoot();
}
/* phead - put out line with proper spacing and indenting */
phead()
{
curpag = newpag++;
if (m1val > 0) {
skip(m1val-1);
PutTitle(header, curpag);
}
skip(m2val);
lineno = m1val + m2val + 1;
}
/* pfoot - put out page footer */
pfoot()
{
skip(m3val);
if (m4val > 0) {
PutTitle(footer, curpag);
skip(m4val-1);
}
}
/* PutTitle - put out title line with optional pagenumber */
PutTitle(line, pageno)
char *line;
{
*line--;
while (*++line)
if (*line == PAGENUM)
printf("%3d", pageno);
else
putchar(*line);
}
/* skip - output n blank lines */
skip(i)
{
while (i--)
putchar('\n');
}
LeadBlank(buf)
char *buf;
{
char *temp;
int i;
temp = buf;
i = 0;
/*
brk();
*/
while (*buf == ' ' || *buf == '\t') {
if (*buf++ == '\t')
i = (i & ~0x07) + 8;
else
i++;
}
if (*buf != '\n' && fill == NO)
tival = i;
while (*buf)
*temp++ = *buf++;
*temp = '\0';
}
GetWord(in, ii, out)
char in[], *out;
int *ii;
{
int i;
char *p;
p = out;
i = *ii;
while (in[i] == ' ' || in[i] == '\t')
i++;
while (in[i] && !isspace(in[i]))
*out++ = in[i++];
*out = '\0';
*ii = i;
return(out - p);
}
PutWord(wrdbuf)
char *wrdbuf;
{
int last, llval, nextra, w;
w = width(wrdbuf);
last = strlen(wrdbuf) + outp + 1;
llval = rmval - tival;
if (outp > 0 && (outw + w > llval || last >= MAXOUT)) {
last -= outp;
nextra = llval - outp + 1;
spread(outbuf, outp, next